package com.yuma.websocketdemo.controller;

import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;


/**
 * WebSocket常用注解：
 *
 * @ServerEndpoint 通过这个 spring boot 就可以知道你暴露出去的 ws 应用的路径，
 * 有点类似我们经常用的@RequestMapping。比如你的启动端口是8080，
 * 而这个注解的值是api，那我们就可以通过 ws://127.0.0.1:8080/api 来连接你的应用
 * @OnOpen 当websocket建立连接成功后会触发这个注解修饰的方法，注意它有一个Session参数
 * @OnClose 当websocket建立的连接断开后会触发这个注解修饰的方法，注意它有一个Session参数
 * @OnMessage 当客户端发送消息到服务端时，会触发这个注解修改的方法，它有一个String入参表明客户端传入的值
 * @OnError 当websocket建立连接时出现异常会触发这个注解修饰的方法，注意它有一个Session参数
 */
@RestController
@ServerEndpoint("/ws/{userId}")
public class WebSocketController {
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") Long userId) {
        System.out.println("建立了链接:" + userId);
        /**
         * 通过WebSocket会话的异步远程连接发送文本消息。
         * getAsyncRemote()获取异步远程连接对象，
         * sendText()方法向客户端发送"hello,I'am server"欢迎消息。
         * 这是在WebSocket连接建立后，服务器主动向客户端发送的响应信息。
         */
        session.getAsyncRemote().sendText("Hello, I'm server");
    }

    @OnMessage
    public void onMessage(Session session, String message, @PathParam("userId") Long userId) {
        System.out.println("服务器端收到了消息:" + message);
        /**
         * 通过WebSocket会话异步发送文本消息回给客户端。
         * 它将用户ID、当前时间和收到的消息内容拼接成一条响应消息，
         * 然后异步发送给对应的客户端连接。
         */
        session.getAsyncRemote().sendText("用户：" + userId + "在" + new Date().toLocaleString() + "发送消息：" + message);
    }

    @OnClose
    public void onClose(Session session, @PathParam("userId") Long userId) {
        System.out.println("关闭了连接：" + userId);
    }

    @OnError
    public void onError(Session session, Throwable ex) {
        System.out.println("连接出错:" + ex.getMessage());
    }
}